package com.onlineMIS.ORM.DAO.headQ.ipad;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.record.PageBreakRecord.Break;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.aop.ThrowsAdvice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.onlineMIS.ORM.DAO.Response;
import com.onlineMIS.ORM.DAO.headQ.SQLServer.ClientDAOImpl;
import com.onlineMIS.ORM.DAO.headQ.SQLServer.SaleHistoryMSDAOImpl;
import com.onlineMIS.ORM.DAO.headQ.barCodeGentor.HeadQEntityTagDaoImpl;
import com.onlineMIS.ORM.DAO.headQ.barCodeGentor.ProductBarcodeDaoImpl;
import com.onlineMIS.ORM.DAO.headQ.barCodeGentor.ProductBarcodePicDaoImpl;
import com.onlineMIS.ORM.DAO.headQ.barCodeGentor.ProductBarcodeService;
import com.onlineMIS.ORM.DAO.headQ.custMgmt.HeadQCustDaoImpl;
import com.onlineMIS.ORM.DAO.headQ.inventory.InventoryOrderDAOImpl;
import com.onlineMIS.ORM.DAO.headQ.inventory.InventoryOrderProductDAOImpl;
import com.onlineMIS.ORM.DAO.headQ.inventory.InventoryService;
import com.onlineMIS.ORM.DAO.headQ.inventoryFlow.HeadQInventoryFlowOrderDAOImpl;
import com.onlineMIS.ORM.DAO.headQ.inventoryFlow.HeadQInventoryFlowOrderProductDAOImpl;
import com.onlineMIS.ORM.DAO.headQ.inventoryFlow.HeadQInventoryStockDAOImpl;
import com.onlineMIS.ORM.DAO.headQ.inventoryFlow.HeadQInventoryStoreDAOImpl;
import com.onlineMIS.ORM.DAO.headQ.user.UserInforDaoImpl;
import com.onlineMIS.ORM.entity.chainS.sales.ChainStoreSalesOrder;
import com.onlineMIS.ORM.entity.headQ.SQLServer.ClientsMS;
import com.onlineMIS.ORM.entity.headQ.SQLServer.RegionMS;
import com.onlineMIS.ORM.entity.headQ.SQLServer.SaleHistory;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.Brand;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.HeadqEntityTag;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.Product;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.ProductBarcode;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.ProductBarcodePic;
import com.onlineMIS.ORM.entity.headQ.custMgmt.HeadQCust;
import com.onlineMIS.ORM.entity.headQ.inventory.HeadqCalculateInventoryVO;
import com.onlineMIS.ORM.entity.headQ.inventory.InventoryOrder;
import com.onlineMIS.ORM.entity.headQ.inventory.InventoryOrderProduct;
import com.onlineMIS.ORM.entity.headQ.inventoryFlow.HeadQInventoryStore;
import com.onlineMIS.ORM.entity.headQ.inventoryFlow.HeadqInventoryFlowOrder;
import com.onlineMIS.ORM.entity.headQ.inventoryFlow.HeadqInventoryFlowOrderProduct;
import com.onlineMIS.ORM.entity.headQ.user.UserInfor;
import com.onlineMIS.action.headQ.ipad.ProductBarcodeVO;
import com.onlineMIS.common.Common_util;
import com.onlineMIS.common.loggerLocal;
import com.onlineMIS.filter.SystemParm;

@Service
public class IpadService {
	public static final int ORDER_MODE_HAND = 1;
	public static final int ORDER_MODE_ONE =0;

	@Autowired
	private HeadQCustDaoImpl headQCustDaoImpl;
	
	@Autowired
	private ProductBarcodeDaoImpl productBarcodeDaoImpl;
	
	@Autowired
	private InventoryOrderDAOImpl inventoryOrderDAOImpl;
	
	@Autowired
	private InventoryOrderProductDAOImpl inventoryOrderProductDAOImpl;
	
	@Autowired
	private ProductBarcodePicDaoImpl productBarcodePicDaoImpl;
	@Autowired
	private ProductBarcodeService pbService;
	
	@Autowired
	private SaleHistoryMSDAOImpl saleHistoryDAOImpl;
	
	@Autowired
	private HeadQInventoryStockDAOImpl headQInventoryStockDAOImpl;
	
	@Autowired
	private HeadQInventoryFlowOrderDAOImpl headQInventoryFlowOrderDAOImpl;
	
	@Autowired
	private HeadQInventoryFlowOrderProductDAOImpl headQInventoryFlowOrderProductDAOImpl;
	
	@Autowired
	private UserInforDaoImpl userInforDaoImpl;
	
	@Autowired
	private HeadQInventoryStoreDAOImpl headQInventoryStoreDAOImpl;
	@Autowired
	private HeadQEntityTagDaoImpl entityTagDaoImpl;

	/**
	 * when people type the pinyin, this service will search the client infroamtion from the jinsuan database
	 * @param pinyin
	 * @return
	 */
	public List<HeadQCust> getClients(String pinyin) {
		pinyin = pinyin.replaceAll(" ", "%");
		List<HeadQCust> clientsMSs = headQCustDaoImpl.selectCustsByPY(pinyin, HeadQCust.STATUS_GOOD);
		
		for (int i = clientsMSs.size()-1; i >=0; i--){
			HeadQCust client= clientsMSs.get(i);
			String name = client.getName();
			if (name.contains("不做") || name.contains("不用"))
				clientsMSs.remove(i);
		}

		return clientsMSs;

	}


	public Response searchByProductCode(String barcodeForm, String productCode, Integer storeId,int storeType, Integer clientId, Integer orderId) {

		productCode = productCode.replaceAll("\\.", "_");
		//System.out.println("-----------" + productCode);
		Response response = new Response();
		
		DetachedCriteria criteria = DetachedCriteria.forClass(ProductBarcode.class);
		DetachedCriteria productCriteria = criteria.createCriteria("product");
		DetachedCriteria brandCriteria = productCriteria.createCriteria("brand");
		
		if (!StringUtils.isEmpty(barcodeForm)) 
			criteria.add(Restrictions.eq("barcode",barcodeForm));
		else 
		    productCriteria.add(Restrictions.like("productCode", productCode, MatchMode.ANYWHERE));
		switch (storeType) {
		    //全部
			case 1:
				break;
			case 2: // 千禧
				brandCriteria.add(Restrictions.eq("belong_To", Brand.BELONG_TO_QX));
				break;
			case 3: // 喜乐仓
				brandCriteria.add(Restrictions.eq("belong_To", Brand.BELONG_TO_XLC));
				break;
			default:
				break;
		}
	
		Set<Integer> statusSet = new HashSet<Integer>();
		statusSet.add(ProductBarcode.STATUS_OK);
		statusSet.add(ProductBarcode.STATUS_NOT_PRODUCE);
		
		criteria.add(Restrictions.in("status", statusSet));
		productCriteria.add(Restrictions.isNull("chainStore"));
		productCriteria.addOrder(Order.desc("year.year_ID"));
		productCriteria.addOrder(Order.desc("quarter.quarter_ID"));
		productCriteria.addOrder(Order.desc("brand.brand_ID"));
		productCriteria.addOrder(Order.asc("productCode"));
		
		//1. 生成CurrentOrderProduct map
		int recordPerPage = Integer.parseInt(SystemParm.getParm("IPAD_DISPLAY_PROD_PER_PAGE"));
		List<ProductBarcode> productBarcodes = productBarcodeDaoImpl.getByCritera(criteria, 0, recordPerPage, true);
		if (productBarcodes == null || productBarcodes.size() == 0){
			response.setReturnValue(null);
		} else {
			List<ProductBarcodeVO> productBarcodeVOs = new ArrayList<ProductBarcodeVO>();
			for (ProductBarcode pb: productBarcodes){
				//String barcode = pb.getBarcode();
				
				//货品库存
				int inventory = 0;
				if(storeId != null)
				    inventory = headQInventoryStockDAOImpl.getProductStock(pb.getId(), storeId, true);
				
				//实际库存
				int inventory2 = 0;
				
				//历史销售
				int orderHis = 0;
				if (clientId != null) {
					List<Integer> statusList = new ArrayList<Integer>();
					statusList.add(InventoryOrder.STATUS_ACCOUNT_COMPLETE);
					orderHis = inventoryOrderDAOImpl.getInventoryProductQuantity(clientId,pb.getId(),statusList, null);
				}
				
				int orderCurrent = 0 ;
				if (orderId != null){
					//当前订单
					InventoryOrderProduct orderProduct = inventoryOrderProductDAOImpl.getByOrderIdProductId(orderId.intValue(), pb.getId());
				    if(orderProduct != null)
					  orderCurrent = orderProduct.getQuantity();
				}
				
				ProductBarcodeVO productBarcodeVO = new ProductBarcodeVO(pb, inventory, orderHis, orderCurrent,inventory2);
				productBarcodeVO.setPicURL(productBarcodePicDaoImpl.getURLPathByBarcode(pb.getBarcode(), ProductBarcodePic.TYPE_PING_MIAN_PIC));
				productBarcodeVOs.add(productBarcodeVO);
			}
			response.setReturnValue(productBarcodeVOs);
		}
		
		return response;		
	}

	@Transactional
	/**
	 * orderMode 是整首还是单件
	 * @param clientIdObj
	 * @param orderIdObj
	 * @param pbId
	 * @param quantity
	 * @param orderScanner
	 * @param orderMode
	 * @return
	 */
	public Response orderProduct(Object clientIdObj, Object orderIdObj, int pbId, int quantity, UserInfor orderScanner, int orderMode) {
		Response response = new Response();
		Map<String, Integer> result = new HashMap<String, Integer>();
	
		
		if (clientIdObj == null){
		   response.setFail("输入客户信息后再选择货品");
		   return response;
		}
		
		int client_id = Integer.valueOf(String.valueOf(clientIdObj));
		

			if (orderIdObj == null){
				HeadQCust clientsMS = headQCustDaoImpl.getTemCust(client_id);
				
				InventoryOrder order = new InventoryOrder();
				order.setClient_id(client_id);
				order.setClient_name(clientsMS.getName() +" " + clientsMS.getArea());
				
				order.setOrder_StartTime(Common_util.getToday());
				order.setOrder_Status(InventoryOrder.STATUS_PDA_DRAFT);
				order.setOrder_type(InventoryOrder.TYPE_SALES_ORDER_W);
				order.setPdaScanner(orderScanner);
				
				ProductBarcode pBarcode = productBarcodeDaoImpl.get(pbId, true);
				Product p = pBarcode.getProduct();
				
				InventoryOrderProduct inventoryOrderProduct= new InventoryOrderProduct();
				inventoryOrderProduct.setIndex(0);
				inventoryOrderProduct.setProductBarcode(pBarcode);
				
				int q = quantity;
				if (orderMode == IpadService.ORDER_MODE_HAND)
					q = quantity * p.getNumPerHand();
				inventoryOrderProduct.setQuantity(q);
				
				double wholePrice = ProductBarcodeDaoImpl.getWholeSalePrice(pBarcode);
				inventoryOrderProduct.setWholeSalePrice(wholePrice);
				
				double totalWholeSalePrice = wholePrice * q;
				order.setTotalWholePrice((int)totalWholeSalePrice);
				order.setTotalQuantity(q);
				
				List<InventoryOrderProduct> orderProducts = new ArrayList<InventoryOrderProduct>();
				orderProducts.add(inventoryOrderProduct);
				
				order.setProduct_List(orderProducts);
				order.putListToSet();
				
				inventoryOrderDAOImpl.save(order, true);
				result.put("orderId", order.getOrder_ID());
				result.put("pbId", pBarcode.getId());
				result.put("cq", p.getNumPerHand());
				
				response.setReturnValue(result);
			} else {
				int orderId = Integer.valueOf(String.valueOf(orderIdObj));
				InventoryOrderProduct orderProduct = inventoryOrderProductDAOImpl.getByOrderIdProductId(orderId, pbId);
				if (orderProduct != null){
					ProductBarcode pBarcode = orderProduct.getProductBarcode();
					Product p = pBarcode.getProduct();
					
					InventoryOrder order = inventoryOrderDAOImpl.get(orderId, true);
					double wholePrice = ProductBarcodeDaoImpl.getWholeSalePrice(pBarcode);
					
					int moreQ = quantity;
					
					if (orderMode == IpadService.ORDER_MODE_HAND) {
						moreQ = quantity * p.getNumPerHand();
					}
					
					int newQ = moreQ + orderProduct.getQuantity();	
					
					if (newQ ==0)
						inventoryOrderProductDAOImpl.delete(orderProduct, true);
					else if (newQ < 0){
						newQ = 0;
						inventoryOrderProductDAOImpl.delete(orderProduct, true);
						moreQ = -orderProduct.getQuantity();
					} else {
						orderProduct.setQuantity(newQ);
						inventoryOrderProductDAOImpl.update(orderProduct, true);
					}
	
					double totalWholeSalePrice = wholePrice * moreQ;
					
					order.setTotalWholePrice((int)(totalWholeSalePrice + order.getTotalWholePrice()));
					order.setTotalQuantity(moreQ + order.getTotalQuantity());
					inventoryOrderDAOImpl.save(order, true);
					
					result.put("orderId", orderId);
					result.put("pbId", pBarcode.getId());
					result.put("cq", newQ);
					
					response.setReturnValue(result);
					
				} else {
					InventoryOrder order = inventoryOrderDAOImpl.get(orderId, true);
					
					ProductBarcode pBarcode = productBarcodeDaoImpl.get(pbId, true);
					Product p = pBarcode.getProduct();
					
					InventoryOrderProduct inventoryOrderProduct= new InventoryOrderProduct();
					inventoryOrderProduct.setIndex(0);
					inventoryOrderProduct.setProductBarcode(pBarcode);
					
					int q = quantity;					
					if (orderMode == IpadService.ORDER_MODE_HAND) {
						q = quantity * p.getNumPerHand();
					}
					
					inventoryOrderProduct.setQuantity(q);
					inventoryOrderProduct.setOrder(order);
					
					double wholePrice = ProductBarcodeDaoImpl.getWholeSalePrice(pBarcode);
					inventoryOrderProduct.setWholeSalePrice(wholePrice);
									
					inventoryOrderProductDAOImpl.saveOrUpdate(inventoryOrderProduct, true);
					
					
					double totalWholeSalePrice = wholePrice * q;
					
					order.setTotalWholePrice((int)(totalWholeSalePrice + order.getTotalWholePrice()));
					order.setTotalQuantity(q + order.getTotalQuantity());
					inventoryOrderDAOImpl.save(order, true);
					
					result.put("orderId", orderId);
					result.put("pbId", pBarcode.getId());
					result.put("cq", p.getNumPerHand());
					
					response.setReturnValue(result);
				}
			}
		
		return response;
	}
	
	@Transactional
	/**
	 * orderMode 是整首还是单件
	 * @param clientIdObj
	 * @param orderIdObj
	 * @param pbId
	 * @param quantity
	 * @param orderScanner
	 * @param orderMode
	 * @return
	 */
	public Response headqOrderProduct(Object clientIdObj, Object orderIdObj,int storeId, int pbId, int quantity, UserInfor orderScanner, int orderMode) {
		Response response = new Response();
		Map<String, Integer> result = new HashMap<String, Integer>();
	
		
		if (clientIdObj == null){
		   response.setFail("输入盘点人员信息后再选择货品");
		   return response;
		}
		
		int client_id = Integer.valueOf(String.valueOf(clientIdObj));
		
			if (orderIdObj == null){

				HeadqInventoryFlowOrder order = new HeadqInventoryFlowOrder();
				
				UserInfor userInfor = userInforDaoImpl.get(client_id, true); 
				order.setCreator(userInfor);
				order.setStoreId(storeId);
				order.setStatus(HeadqInventoryFlowOrder.STATUS_DRAFT);
				order.setType(HeadqInventoryFlowOrder.INVENTORY_ORDER);
				order.setComment("盘点系统单据");
				order.setOrderDate(new Date());
				
				
				ProductBarcode pBarcode = productBarcodeDaoImpl.get(pbId, true);
				Product p = pBarcode.getProduct();
				
				HeadqInventoryFlowOrderProduct inventoryOrderProduct= new HeadqInventoryFlowOrderProduct();
				inventoryOrderProduct.setIndex(0);
				inventoryOrderProduct.setProductBarcode(pBarcode);
				
				int q = quantity;
				if (orderMode == IpadService.ORDER_MODE_HAND)
					q = quantity * p.getNumPerHand();
				inventoryOrderProduct.setQuantity(q);
				
				double wholePrice = ProductBarcodeDaoImpl.getWholeSalePrice(pBarcode);
				inventoryOrderProduct.setWholePrice(wholePrice);
				
				double totalWholeSalePrice = wholePrice * q;
				order.setTotalCost(p.getRecCost() * q);
				order.setTotalWholePrice((int)totalWholeSalePrice);
				order.setTotalQuantity(q);
				
				List<HeadqInventoryFlowOrderProduct> orderProducts = new ArrayList<HeadqInventoryFlowOrderProduct>();
				orderProducts.add(inventoryOrderProduct);
				
				order.setProductList(orderProducts);
				order.putListToSet();
				
				headQInventoryFlowOrderDAOImpl.save(order, true);
				
				result.put("orderId", order.getId());
				result.put("pbId", pbId);
				result.put("cq", quantity);
				
				response.setReturnValue(result);
			} else {
				int orderId = Integer.valueOf(String.valueOf(orderIdObj));
				HeadqInventoryFlowOrderProduct orderProduct = headQInventoryFlowOrderProductDAOImpl.selectProductsByOrderIdAndPbId(orderId,pbId);
				if (orderProduct != null){
					ProductBarcode pBarcode = orderProduct.getProductBarcode();
					Product p = pBarcode.getProduct();
					
					HeadqInventoryFlowOrder order = headQInventoryFlowOrderDAOImpl.get(orderId, true);
					double wholePrice = ProductBarcodeDaoImpl.getWholeSalePrice(pBarcode);
					
					int moreQ = quantity;
					
					if (orderMode == IpadService.ORDER_MODE_HAND) {
						moreQ = quantity * p.getNumPerHand();
					}
					
					int newQ = moreQ + orderProduct.getQuantity();	
					
					if (newQ ==0)
						headQInventoryFlowOrderProductDAOImpl.delete(orderProduct, true);
					else if (newQ < 0){
						newQ = 0;
						headQInventoryFlowOrderProductDAOImpl.delete(orderProduct, true);
						moreQ = -orderProduct.getQuantity();
					} else {
						orderProduct.setQuantity(newQ);
						headQInventoryFlowOrderProductDAOImpl.update(orderProduct, true);
					}
	
					double totalWholeSalePrice = wholePrice * moreQ;
					
					order.setTotalWholePrice((int)(totalWholeSalePrice + order.getTotalWholePrice()));
					order.setTotalQuantity(moreQ + order.getTotalQuantity());
					headQInventoryFlowOrderDAOImpl.save(order, true);
					
					result.put("orderId", orderId);
					result.put("pbId", pBarcode.getId());
					result.put("cq", newQ);
					
					response.setReturnValue(result);
					
				} else {
					HeadqInventoryFlowOrder order = headQInventoryFlowOrderDAOImpl.get(orderId, true);
					
					ProductBarcode pBarcode = productBarcodeDaoImpl.get(pbId, true);
					Product p = pBarcode.getProduct();
					
					HeadqInventoryFlowOrderProduct inventoryOrderProduct= new HeadqInventoryFlowOrderProduct();
					inventoryOrderProduct.setIndex(0);
					inventoryOrderProduct.setProductBarcode(pBarcode);
					
					int q = quantity;					
					if (orderMode == IpadService.ORDER_MODE_HAND) {
						q = quantity * p.getNumPerHand();
					}
					
					inventoryOrderProduct.setQuantity(q);
					inventoryOrderProduct.setFlowOrder(order);
					
					double wholePrice = ProductBarcodeDaoImpl.getWholeSalePrice(pBarcode);
					inventoryOrderProduct.setWholePrice(wholePrice);
									
					headQInventoryFlowOrderProductDAOImpl.saveOrUpdate(inventoryOrderProduct, true);
					
					
					double totalWholeSalePrice = wholePrice * q;
					
					order.setTotalWholePrice((int)(totalWholeSalePrice + order.getTotalWholePrice()));
					order.setTotalQuantity(q + order.getTotalQuantity());
					headQInventoryFlowOrderDAOImpl.save(order, true);
					
					result.put("orderId", orderId);
					result.put("pbId", pBarcode.getId());
					result.put("cq", p.getNumPerHand());
					
					response.setReturnValue(result);
				}
			}
		
		return response;
	}
	
	/**
	 * 获取盘点的单据
	 * @param orderId
	 * @return
	 */
	public Response getOrderHeadInfo4Pandian(int orderId) {
		Response response = new Response();
		
		HeadqInventoryFlowOrder order = headQInventoryFlowOrderDAOImpl.get(orderId, true);
	
		response.setReturnValue(order);
		
		return response;
	}
	
	public Response getOrderHeadInfo(int orderId) {
		Response response = new Response();
		
		InventoryOrder order = inventoryOrderDAOImpl.get(orderId, true);
	
		response.setReturnValue(order);
		
		return response;
	}


	@Transactional
	public Response getOrder4Pandian(Object orderIdObj) {
		Response response = new Response();
		if (orderIdObj == null){
		   response.setFail("没有找到订单号,订单号为空");
		   return response;
		}
		
		int orderId = Integer.parseInt(String.valueOf(orderIdObj));
		HeadqInventoryFlowOrder order = headQInventoryFlowOrderDAOImpl.retrieveOrder(orderId);
		List<HeadqInventoryFlowOrderProduct> list = headQInventoryFlowOrderProductDAOImpl.selectProductsByOrderId(orderId);
		order.setProductList(list);	
		response.setReturnValue(order);
		return response;
	}
	
	@Transactional
	public Response getOrder(Object orderIdObj) {
		Response response = new Response();
		if (orderIdObj == null){
		   response.setFail("没有找到订单号,订单号为空");
		   return response;
		}
		
		int orderId = Integer.parseInt(String.valueOf(orderIdObj));
		
		InventoryOrder order = inventoryOrderDAOImpl.retrieveOrder(orderId);
		order.putSetToList();
		
		response.setReturnValue(order);
		
		return response;
	}

	/**
	 * 处理单据，如果orderId(来自表单不为空优先出俩)
	 * @param orderId
	 * @param orderIdObj
	 * @param loginUser
	 * @param comment
	 * @return
	 */
	@Transactional
	public Response submitOrder4Pandian(int orderIdForm, Object orderIdObj, UserInfor loginUser, String comment) {
		Response response = new Response();
		
		if (orderIdObj == null && orderIdForm==0){
			   response.setFail("没有订单信息无法提交单据");
			   return response;
		} 
			
		int orderId = 0;
		
		if (orderIdForm != 0)
			orderId = orderIdForm;
		else 
			orderId = Integer.valueOf(String.valueOf(orderIdObj));
		
		HeadqInventoryFlowOrder order = headQInventoryFlowOrderDAOImpl.retrieveOrder(orderId);
		
	    //part 1. to set the selected price and whole price
		Set<String> barcodes = new HashSet<String>();
		
		// 1.1 to store the non-duplicated product code in a sequence list for new order
		Set<HeadqInventoryFlowOrderProduct> orderProducts = order.getProductSet();
		for (HeadqInventoryFlowOrderProduct orderProduct: orderProducts){
			if (orderProduct!= null && orderProduct.getProductBarcode() != null && !orderProduct.getProductBarcode().getBarcode().equals("")){
			   String barcode = orderProduct.getProductBarcode().getBarcode();
			   barcodes.add(barcode);
			}
		}
		
		Map<String, ProductBarcode> productMap = productBarcodeDaoImpl.getProductMapByBarcode(barcodes);
		
		//1.2 to set the re-cost, selected price, whole price, discount
		//               totalQ, totalWhole, totalRecost, totalSalePrice
		int totalQ = 0;
		int totalWholePrice = 0;
		int totalCost = 0;
        int index = 0;
        
        List<HeadqInventoryFlowOrderProduct> newOrderProducts = new ArrayList<HeadqInventoryFlowOrderProduct>();
		newOrderProducts.addAll(orderProducts);
		for (HeadqInventoryFlowOrderProduct orderProduct: orderProducts){

			if (orderProduct == null || orderProduct.getProductBarcode()==null )
				continue;

			orderProduct.setIndex(index++);
			
			String barcode = orderProduct.getProductBarcode().getBarcode();
			ProductBarcode productBarcode = productMap.get(barcode);
			
			if (productBarcode == null){
				loggerLocal.error("Error to get the product barcode information :" + barcode);
			} else {
				Product product = productBarcode.getProduct();

				double selectedPrice = productBarcodeDaoImpl.getSelectedSalePrice(productBarcode);
				double discount = 1;
				if (selectedPrice == product.getSalesPriceFactory())
					discount = product.getDiscount();
				
				int quantity = orderProduct.getQuantity();
				double wholePrice = selectedPrice * discount;
				double cost = product.getRecCost();
				
				orderProduct.setWholePrice(wholePrice);
				orderProduct.setCost(cost);
				
				
				totalQ += quantity;
				totalCost += quantity * cost;
				totalWholePrice += wholePrice * quantity;
				orderProduct.setQuantity(totalQ);
				orderProduct.setTotalCost(totalCost);
				orderProduct.setTotalWholePrice(totalWholePrice);
			}

		}
		
		if (!StringUtils.isEmpty(comment))
	        order.setComment(order.getComment()+":"+comment);
	    order.setTotalQuantity(totalQ);
	    order.setTotalCost(Common_util.roundDouble(totalCost,2));

	    order.setTotalWholePrice(Common_util.roundDouble(totalWholePrice,2));
		
	    order.setProductList(newOrderProducts);
		order.buildIndex();
		headQInventoryFlowOrderDAOImpl.saveOrUpdate(order,true);
	    
	    response.setQuickValue(Response.SUCCESS, "");
		
		
		return response;
	}
	
	/**
	 * 处理单据，如果orderId(来自表单不为空优先出俩)
	 * @param orderId
	 * @param orderIdObj
	 * @param loginUser
	 * @param comment
	 * @return
	 */
	@Transactional
	public Response submitOrder(int orderIdForm, Object orderIdObj, UserInfor loginUser, String comment) {
		Response response = new Response();
		
		if (orderIdObj == null && orderIdForm==0){
			   response.setFail("没有订单信息无法提交单据");
			   return response;
		} 
			
		
		int orderId = 0;
		
		if (orderIdForm != 0)
			orderId = orderIdForm;
		else 
			orderId = Integer.valueOf(String.valueOf(orderIdObj));
		
		InventoryOrder order = inventoryOrderDAOImpl.retrieveOrder(orderId);
		
		//验证部分，要验证千禧客户不能有禧乐仓货品，禧乐仓客户不能有千禧货品
		response = validateClientAndProduct(order);
		if (!response.isSuccess()) {
			return response;
		}
		
	    //part 1. to set the selected price and whole price
		Set<String> barcodes = new HashSet<String>();
		// 1.1 to store the non-duplicated product code in a sequence list for new order
		Set<InventoryOrderProduct> orderProducts = order.getProduct_Set();
		for (InventoryOrderProduct orderProduct: orderProducts){
			
			if (orderProduct!= null && orderProduct.getProductBarcode() != null && !orderProduct.getProductBarcode().getBarcode().equals("")){
			   String barcode = orderProduct.getProductBarcode().getBarcode();
			   loggerLocal.info(orderId + "," + barcode);
			   if (barcodes.contains(barcode)) {
				   response.setFail("单据中出现重复条码 : " + barcode);
				   return response;
			   } else 
			       barcodes.add(barcode);
			}
		}
		
		Map<String, ProductBarcode> productMap = productBarcodeDaoImpl.getProductMapByBarcode(barcodes);
		
		//1.2 to set the re-cost, selected price, whole price, discount
		//               totalQ, totalWhole, totalRecost, totalSalePrice
		int totalQ = 0;
		int totalWholePrice = 0;
		int totalCost = 0;
		int totalSalePrice = 0;
        int index = 0;
        
        List<InventoryOrderProduct> newOrderProducts = new ArrayList<InventoryOrderProduct>();
		newOrderProducts.addAll(orderProducts);
		Collections.sort(newOrderProducts, new com.onlineMIS.sorter.SortByBrandProductCode());
        
		for (InventoryOrderProduct orderProduct: orderProducts){

			if (orderProduct == null || orderProduct.getProductBarcode()==null )
				continue;

			orderProduct.setIndex(index++);
			
			String barcode = orderProduct.getProductBarcode().getBarcode();
			ProductBarcode productBarcode = productMap.get(barcode);
			
			if (productBarcode == null){
				loggerLocal.error("Error to get the product barcode information :" + barcode);
			} else {
				Product product = productBarcode.getProduct();

				double selectedPrice = productBarcodeDaoImpl.getSelectedSalePrice(productBarcode);
				double discount = 1;
				if (selectedPrice == product.getSalesPriceFactory())
					discount = product.getDiscount();
				
				int quantity = orderProduct.getQuantity();
				double wholePrice = selectedPrice * discount;
				double cost = product.getRecCost();
				double salePrice = product.getSalesPrice();
				
//				orderProduct.setDiscount(discount);
//				orderProduct.setSalePriceSelected(selectedPrice);
//				orderProduct.setWholeSalePrice(Common_util.roundDouble(wholePrice,2));
//				orderProduct.setSalesPrice(salePrice);
//				orderProduct.setProductBarcode(productBarcode);
//				orderProduct.setRecCost(cost);
				
				totalQ += quantity;
				totalCost += quantity * cost;
				totalWholePrice += wholePrice * quantity;
				totalSalePrice += salePrice * quantity;
			}

		}

	    order.setPdaScanner(loginUser);
		order.setOrder_scanner(loginUser);
//		order.setClient_name(client.getName() + "," + client.getRegion().getName());
		if (!StringUtils.isEmpty(comment))
	        order.setComment2(comment);
	    order.setOrder_StartTime(new Date());
	    order.setOrder_type(InventoryOrder.TYPE_SALES_ORDER_W);
	    order.setTotalQuantity(totalQ);
	    order.setTotalRecCost(Common_util.roundDouble(totalCost,2));
	    order.setTotalRetailPrice(Common_util.roundDouble(totalSalePrice,2));
	    order.setTotalWholePrice(Common_util.roundDouble(totalWholePrice,2));
	    order.setOrder_Status(InventoryOrder.STATUS_PDA_COMPLETE);
		
	    order.setProduct_List(newOrderProducts);
	    order.setProduct_Set(new HashSet<InventoryOrderProduct>());
		order.buildIndex();
		order.putListToSet();
		inventoryOrderDAOImpl.saveOrUpdate(order,true);
	    
	    response.setQuickValue(Response.SUCCESS, "");
		
		
		return response;
	}
	
	/**
	 * 验证客户和货品必须匹配
	 * @return
	 */
	private Response validateClientAndProduct(InventoryOrder order) {
			Response response = new Response();
			int belongTo = 0;
			String errorMsg = "";
			
			String custTitle = "";

			// 1.判断客户是千禧客户 || 禧乐仓客户
			HeadqEntityTag qxEntityTag = entityTagDaoImpl.selectEntityTag(order.getClient_id(),
					SystemParm.getQxCustTagId());
			HeadqEntityTag xEntityTag = null;
			if (qxEntityTag != null) {
				belongTo = Common_util.QX_RANGE;
				custTitle = "千禧";
			} else {
				xEntityTag = entityTagDaoImpl.selectEntityTag(order.getClient_id(),
						SystemParm.getXlcCustTagId());
				if (xEntityTag != null) {
					belongTo = Common_util.XLC_RANGE;
					custTitle = "禧乐仓";
				}
			}
			if (qxEntityTag == null && xEntityTag == null) {
				response.setFail("当前客户未选择归属标签,请联系系统管理员为客户添加标签");
			} else {
				for (InventoryOrderProduct product : order.getProduct_Set()) {
							Brand brand = product.getProductBarcode().getProduct().getBrand();
							if (brand != null && brand.getBelong_To() != belongTo) {
								errorMsg += custTitle+ "客户无法选择" + Brand.belongToMap.get(brand.getBelong_To()) + "货品，货号："
										+ product.getProductBarcode().getProduct().getProductCode()+ "\n";
								response.setReturnCode(Response.FAIL);
							}
				}
				if (!response.isSuccess())
					  response.setFail(errorMsg);
			}
			return response;
	}


	public Response getDraftOrders4Pandian(UserInfor loginUser) {
		Response response = new Response();
		DetachedCriteria criteria = DetachedCriteria.forClass(HeadqInventoryFlowOrder.class,"order");
		criteria.add(Restrictions.eq("type", HeadqInventoryFlowOrder.INVENTORY_ORDER));
		criteria.add(Restrictions.eq("status", HeadqInventoryFlowOrder.STATUS_DRAFT));
		criteria.add(Restrictions.eq("creator.user_id", loginUser.getUser_id()));
		criteria.addOrder(Order.desc("orderDate"));
	
		List<HeadqInventoryFlowOrder> orders = headQInventoryFlowOrderDAOImpl.getByCritera(criteria, true);
		if (orders.size() != 0) {
			for (HeadqInventoryFlowOrder headqInventoryFlowOrder : orders) {
				HeadQInventoryStore store = headQInventoryStoreDAOImpl.get(headqInventoryFlowOrder.getStoreId(), true);
				if (store != null) {
					headqInventoryFlowOrder.setStoreName(store.getName());
				}else {
					headqInventoryFlowOrder.setStoreName("未知库房");
				}
			}
		}
		
		response.setReturnValue(orders);
		return response;
	}
	
	public Response getDraftOrders(UserInfor loginUser) {
		Response response = new Response();
		
		DetachedCriteria criteria = DetachedCriteria.forClass(InventoryOrder.class,"order");
		criteria.add(Restrictions.eq("order.order_Status", InventoryOrder.STATUS_PDA_DRAFT));
		criteria.add(Restrictions.eq("pdaScanner.user_id", loginUser.getUser_id()));
	
		List<InventoryOrder> orders = inventoryOrderDAOImpl.search(criteria);
		
		response.setReturnValue(orders);
		
		return response;
	}

	public Response deleteOrder4Pandian(int orderId) {
        Response response = new Response();
        
		
        String hql_order = "UPDATE HeadqInventoryFlowOrder i set i.status = ? where id = ?";
		Object[] values = {HeadqInventoryFlowOrder.STATUS_DELETED,orderId};
			
		headQInventoryFlowOrderDAOImpl.executeHQLUpdateDelete(hql_order, values, true);
		response.setReturnCode(Response.SUCCESS);
        
        return response;
	}
	
	public Response deleteOrder(int orderId) {
        Response response = new Response();
		
        String hql_order = "UPDATE InventoryOrder i set i.order_Status = ? where order_ID = ?";
		Object[] values = {InventoryOrder.STATUS_DELETED,orderId};
			
		inventoryOrderDAOImpl.executeHQLUpdateDelete(hql_order, values, true);
		response.setReturnCode(Response.SUCCESS);
        
        return response;
	}

	@Transactional
	public Response orderProduct4Pandian(Object clientIdObj, Object orderIdObj,
			String barcode, Integer storeId, int quantity, UserInfor loginUser, int orderMode) {
		Response response = new Response();
		
		ProductBarcode pb = productBarcodeDaoImpl.getByBarcode(barcode);
		if (pb == null){
			response.setFail("无法找到此条码的货品");
			return response;
		} else if (clientIdObj == null) {
			response.setFail("请先选择客户再继续选货");
			return response;
		} else {
			response = headqOrderProduct(clientIdObj, orderIdObj,storeId, pb.getId(), quantity, loginUser, orderMode);
			if (response.isSuccess()){
				int clientId = (int)clientIdObj;
				
				//系统库存
				int inventory = headQInventoryStockDAOImpl.getProductStock(pb.getId(), storeId, true);
				
				//除去pda草稿(一周内),仓库草稿(一周内),其他状态数量的库存
				Map<String, Object> result = (Map) response.getReturnValue();
				Integer thisOrderId = (Integer)result.get("orderId");
				int inventory2= this.getCorrectInventory(inventory,barcode, storeId, thisOrderId);
				
				//历史发货数量，
				int orderHis = 0;
//				orderHis = inventoryOrderDAOImpl.getQuantityBefore(pb.getId(),clientId);

				
				//当前订货需数量
				int orderCurrent = 0 ;
				Integer orderId = (Integer) result.get("orderId");
				if (orderId != null){
					InventoryOrderProduct orderProduct = inventoryOrderProductDAOImpl.getByOrderIdProductId(orderId.intValue(), pb.getId());
				    if(orderProduct != null)
					  orderCurrent = orderProduct.getQuantity();
				} 
				
				//历史选货
				int quantityHisOrdered = 0;
				List<Integer> statusList2 = new ArrayList<Integer>();
				statusList2.add(InventoryOrder.STATUS_PDA_DRAFT);
				statusList2.add(InventoryOrder.STATUS_PDA_COMPLETE);
				quantityHisOrdered = inventoryOrderDAOImpl.getInventoryProductQuantity(clientId,pb.getId(),statusList2, null);
				quantityHisOrdered -= orderCurrent;

				ProductBarcodeVO productBarcodeVO = new ProductBarcodeVO(pb, inventory, orderHis, orderCurrent, inventory2);
				productBarcodeVO.setOrderHisSelect(quantityHisOrdered);

				result.put("product", productBarcodeVO.toString());
				result.put("imgURL",productBarcodePicDaoImpl.getURLPathByBarcode(pb.getBarcode(), ProductBarcodePic.TYPE_PING_MIAN_PIC));
				
				response.setReturnValue(result);
			}
			
			return response;
		}
	}
	
	@Transactional
	public Response orderProduct(Object clientIdObj, Object orderIdObj,
			String barcode, Integer storeId, int quantity, UserInfor loginUser, int orderMode) {
		Response response = new Response();
		
		ProductBarcode pb = productBarcodeDaoImpl.getByBarcode(barcode);
		if (pb == null){
			response.setFail("无法找到此条码的货品");
			return response;
		} else if (clientIdObj == null) {
			response.setFail("请先选择客户再继续选货");
			return response;
		} else {
			response = orderProduct(clientIdObj, orderIdObj, pb.getId(), quantity, loginUser, orderMode);
			if (response.isSuccess()){
				int clientId = (int)clientIdObj;
				
				//系统库存
				int inventory = headQInventoryStockDAOImpl.getProductStock(pb.getId(), storeId, true);
				
				//除去pda草稿(一周内),仓库草稿(一周内),其他状态数量的库存
				Map<String, Object> result = (Map) response.getReturnValue();
				Integer thisOrderId = (Integer)result.get("orderId");
				int inventory2= this.getCorrectInventory(inventory,barcode, storeId, thisOrderId);
				
				//历史发货数量，
				int orderHis = 0;
				orderHis = inventoryOrderDAOImpl.getQuantityBefore(pb.getId(),clientId);

				
				//当前订货需数量
				int orderCurrent = 0 ;
				Integer orderId = (Integer) result.get("orderId");
				if (orderId != null){
					InventoryOrderProduct orderProduct = inventoryOrderProductDAOImpl.getByOrderIdProductId(orderId.intValue(), pb.getId());
				    if(orderProduct != null)
					  orderCurrent = orderProduct.getQuantity();
				} 
				
				//历史选货
				int quantityHisOrdered = 0;
				List<Integer> statusList2 = new ArrayList<Integer>();
				statusList2.add(InventoryOrder.STATUS_PDA_DRAFT);
				statusList2.add(InventoryOrder.STATUS_PDA_COMPLETE);
				statusList2.add(InventoryOrder.STATUS_PEIHUO_INPROCESS);
				statusList2.add(InventoryOrder.STATUS_PEIHUO_COMPLETE);
				quantityHisOrdered = inventoryOrderDAOImpl.getInventoryProductQuantity(clientId,pb.getId(),statusList2, null);
				quantityHisOrdered -= orderCurrent;

				ProductBarcodeVO productBarcodeVO = new ProductBarcodeVO(pb, inventory, orderHis, orderCurrent, inventory2);
				productBarcodeVO.setOrderHisSelect(quantityHisOrdered);

				result.put("product", productBarcodeVO.toString());
				result.put("imgURL",productBarcodePicDaoImpl.getURLPathByBarcode(pb.getBarcode(), ProductBarcodePic.TYPE_PING_MIAN_PIC));
				
				response.setReturnValue(result);
			}
			
			return response;
		}
	}

	
	/**
	 * 获取更准确的库存数量
	 * @param barcode
	 * @param storeId
	 * @return
	 */
	private int getCorrectInventory(int jinsuanInventory,String barcode, Integer storeId, int orderId) {
		Date today = Common_util.getToday();
		Date lastWeekDate = Common_util.calcualteDate(today, -7);		
		String clientIdExclude = "(4,2044)";

		//获取一周内 pda 草稿 和仓库草稿
		HeadqCalculateInventoryVO inventoryVO = new HeadqCalculateInventoryVO(barcode);
		
		ProductBarcode pBarcode = productBarcodeDaoImpl.getByProductBarcode(barcode);
		if (pBarcode != null) {
			String sql_draft = "SELECT SUM(p.quantity), p.order.order_type FROM InventoryOrderProduct p WHERE  p.productBarcode.id=? AND p.order.order_StartTime BETWEEN ? AND ? AND p.order.client_id NOT IN " + clientIdExclude +" AND p.order.order_Status IN (1,2,6,7,8,9) AND p.order.order_ID <> ? GROUP BY p.order.order_type";
			Object[] value_sql_draft = new Object[]{pBarcode.getId(),lastWeekDate, today,orderId};
			List<Object> salesdraft = (List<Object>)inventoryOrderDAOImpl.executeHQLSelect(sql_draft, value_sql_draft,null, true);
			
			for (Object resultObject : salesdraft){
				Object[] sales = (Object[])resultObject;
				int quantity = Common_util.getInt(sales[0]);
				int orderType = Common_util.getInt(sales[1]);	
				
				inventoryVO.addQ(orderType, quantity);
			}
		}				
		return jinsuanInventory + inventoryVO.getQuantity();
	}

	/**
	 * 复制ipad 选货 的单据
	 * @param orderId
	 * @return
	 */
	@Transactional
	public Response copyOrder(int orderId, UserInfor loginUserInfor) {
		Response response = new Response();
		
		if (orderId > 0) {
			InventoryOrder orderInDB = inventoryOrderDAOImpl.retrieveOrder(orderId);
			InventoryOrder order = inventoryOrderDAOImpl.copy(orderInDB);
			String comment = order.getComment2();

			order.setComment2(comment + "\n 复制于单据" + orderId);
			order.setOrder_Status(InventoryOrder.STATUS_PDA_DRAFT);
			order.setImportTimes(0);

			inventoryOrderDAOImpl.save(order, true);

			response.setReturnCode(Response.SUCCESS);
			response.setReturnValue(order.getOrder_ID());
		} else {
			response.setFail("单据" +orderId +" 不存在");
		}
		
		return response;
	}

	/**
	 * 用户重新选择 客户名字
	 * @param orderIdObj
	 * @param clientId
	 */
	@Transactional
	public Response changeCustForOrder(int orderId, int newClientId) {
		Response response = new Response();
		InventoryOrder order = inventoryOrderDAOImpl.get(orderId, true);
		if (order != null) {
			HeadQCust clientsMS = headQCustDaoImpl.getTemCust(newClientId);
			if (clientsMS != null) {
				order.setClient_id(clientsMS.getId());
				order.setClient_name(clientsMS.getName());
				
				inventoryOrderDAOImpl.update(order, true);
				
				response.setSuccess("");
			} else 
				response.setFail("无法选择到用户 : " + newClientId);
		} else 
			response.setFail("当前客户单据 " + orderId + " 不存在");
		
		return response;
	}

	/**
	 * 提交盘点单据
	 * @param orderId
	 * @param comment
	 * @return
	 */
	public Response submitHeadqInventoryOrder(int orderId, String comment) {
		Response response = new Response();
		HeadqInventoryFlowOrder order = headQInventoryFlowOrderDAOImpl.get(orderId, true);
		if (order != null) {
			order.setComment(comment);			
			headQInventoryFlowOrderDAOImpl.update(order, true);				
			response.setSuccess("");
		} else 
			response.setFail("当前客户单据 " + orderId + " 不存在");		
		return response;
	}


	/**
	 * c选择客户
	 * @param clientId
	 * @return
	 */
	public Response chooseCustById(int clientId) {
		Response response = new Response();
		
		HeadQCust headQCust = headQCustDaoImpl.getTemCust(clientId);
		
		if (headQCust != null) {
			response.setReturnValue(headQCust);;
		} else {
			response.setFail("无法找到客户");
		}
		
		return response;
	}

}
